plotly

As of v0.6, fivecentplots plotly can be used as the plotting engine instead of matplotlib.

Setup

First-time setup:

plotly is not currently part of the default pacakge requirements for fcp so it is not automatically installed. For inline usage:


pip install plotly

To save and/or show plotly images as .png files automatically with keyword save or show, an additional package install is required:


pip install kaleido

Switching engines:

Since matplotlib is the default plotting engine in fivecentplots, the user must manually invoke the plotly engine. This can be done on a per-plot basis via the engine kwarg or by updating the global kwargs so the change persists within the users current interactive environment

Per-plot:


fcp.plot(df, x=‘x’, y=‘y’, engine=‘plotly’)

Global:


fcp.KWARGS[‘engine’] = ‘plotly’

Themes:

Due to differences between plotting libraries, it was found that the default fivecentplots theme files were not ideal in plotly. It is also therefore recommended to update to a plotly-specific theme when using this engine:


fcp.set_theme(‘gray_plotly’)

Maturity:

All plot types except gantt have been ported to plotly with some base level of support. However, feature parity with matplotlib has not yet been achieved. Please open a new support issue if a needed feature is missing.

Some plot examples are demonstrated below, but the demonstration is not exhaustive and many other plot configurations are still available.

Imports


import fivecentplots as fcp
import pandas as pd
import imageio.v3 as imageio
import cv2
from pathlib import Path

Engine and themes


fcp.KWARGS['inline'] = True
fcp.KWARGS['engine'] = 'plotly'

fcp.set_theme('gray_plotly')
Previous theme file found! Renaming to "defaults_old.py" and copying theme "gray_plotly"...done!

Sample data

Several data sets are used in this tutorial:

x-y data


df_xy = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data.csv')
df_xy.head(10)

Substrate Target Wavelength Boost Level Temperature [C] Die Voltage I Set I [A]
0 Si 450 0.2 25 (1,1) 0.0 0.0 0.0
1 Si 450 0.2 25 (1,1) 0.1 0.0 0.0
2 Si 450 0.2 25 (1,1) 0.2 0.0 0.0
3 Si 450 0.2 25 (1,1) 0.3 0.0 0.0
4 Si 450 0.2 25 (1,1) 0.4 0.0 0.0
5 Si 450 0.2 25 (1,1) 0.5 0.0 0.0
6 Si 450 0.2 25 (1,1) 0.6 0.0 0.0
7 Si 450 0.2 25 (1,1) 0.7 0.0 0.0
8 Si 450 0.2 25 (1,1) 0.8 0.0 0.0
9 Si 450 0.2 25 (1,1) 0.9 0.0 0.0

Time series data


ts = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_ts.csv')
ts.head()

Date Happiness Quotient
0 1/1/2015 16.088954
1 1/2/2015 18.186724
2 1/3/2015 35.744313
3 1/4/2015 38.134045
4 1/5/2015 46.147279

Bar plot data


df_bar = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_bar.csv')
df_bar.head()

Liquid pH Measurement T [C]
0 Lemon juice 2.4 A 25
1 Orange juice 3.5 A 25
2 Battery acid 1.0 A 25
3 Bottled water 6.7 A 25
4 Coke 3.0 A 25

Box plot data


df_box = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_box.csv')
df_box.head()

Batch Sample Region Value ID
0 101 1 Alpha123 3.5 ID701223A
1 101 1 Alpha123 0.0 ID7700-1222B
2 101 1 Alpha123 3.3 ID701223A
3 101 1 Alpha123 3.2 ID7700-1222B
4 101 1 Alpha123 4.0 ID701223A

Contour data


df_contour = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_contour.csv')
df_contour.head()

Experiment Batch X Y Value
0 Control 101 1 -4 3.5
1 Control 101 1 -2 2.1
2 Control 101 1 0 3.3
3 Control 101 1 2 3.2
4 Control 101 1 4 4.0

Heatmap data


df_heatmap = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_heatmap.csv')
df_heatmap.head()

Player Category Average
0 Lebron James Points 27.5
1 Lebron James Assists 9.1
2 Lebron James Rebounds 8.6
3 Lebron James Blocks 0.9
4 James Harden Points 30.4

Histogram data


df_hist = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_box.csv')
img_hist = cv2.imread(str(Path(fcp.__file__).parent / 'test_data/imshow_cat_pirate.png'))

Image data


img_bgr = cv2.imread(str(Path(fcp.__file__).parent / 'test_data/imshow_cat_pirate.png'))
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

plot

No legend


fcp.plot(df_xy, x='Voltage', y='I [A]', lines=False, ax_size=[400, 400])

Filtered


fcp.plot(df_xy, x='Voltage', y='I [A]', title='IV Data', lines=False,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Legend


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Log axis

Note

symlog and logit not yet supported


fcp.plot(df_xy, x='Voltage', y='I [A]', ax_scale='loglog', legend='Die', xmin=0.9, xmax=2.1, grid_minor=True,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Categorical ticks


fcp.plot(df_xy, x='Die', y='I [A]',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25 & Voltage==1.5')

Time series


fcp.plot(ts, x='Date', y='Happiness Quotient', markers=False, ax_size=[1000, 250])

Secondary axes


fcp.plot(df_xy, x='Voltage', y=['Voltage', 'I [A]'], twin_x=True, legend='Die',
         grid_major_y2=True, grid_major_y2_style='--', y2max=1.4,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25 & Die=="(-1,2)"')

Multiple x & y values


fcp.plot(df_xy, x=['Boost Level', 'I [A]'], y=['Voltage', 'Temperature [C]'], legend='Die',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Grouping

Row plot


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die', row='Boost Level', ax_size=[225, 225], legend_edge_color='#000000',
         filter='Substrate=="Si" & Target Wavelength==450 & Temperature [C]==25', label_row_fill_color='#000000', ax_edge_width=4,
         label_row_font_color='#ff0000', label_row_edge_color='#0000ff', label_row_edge_width=2, legend_edge_width=3)

Column plot


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die', col='Boost Level', ax_size=[225, 225], legend_edge_color='#000000',
         filter='Substrate=="Si" & Target Wavelength==450 & Temperature [C]==25', label_col_fill_color='#000000', label_col_font_color='#ff0000')

Row x column grid


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die', col='Boost Level', row='Temperature [C]',
         modebar_visible=True, modebar_fill_color='#000000', ax_edge_width=1, ymin=0,
         ax_size=[225, 225], filter='Substrate=="Si" & Target Wavelength==450', label_rc_font_size=13)

Wrap plot


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die', wrap=['Temperature [C]', 'Boost Level'],
         ax_size=[225, 225], filter='Substrate=="Si" & Target Wavelength==450', label_rc_font_size=13)

Horizontal & vertical lines


fcp.plot(df_xy, x='Voltage', y='I [A]', title='IV Data', lines=False, legend=True,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25',
         ax_hlines=[(0, '#FF0000', '--', 3, 1, 'Open', '#555555', 0.25), 1.2],
         ax_vlines=[(0.6, '#0000ff', ':'), (1, '#00FF00')])

Curve fitting


fcp.plot(df_xy, x='Voltage', y='I [A]', title='IV Data', lines=False,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25',
         fit=1, fit_eqn=True, fit_rsq=True, fit_range_x=[1.3, 2])

Stat Lines


fcp.plot(df_xy, x='Voltage', y=['Boost Level', 'I [A]'], legend=True, stat='median',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Confidence intervals

To demonstrate this feature we will use a special dataset:


df_interval = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_interval.csv')
df_interval.head()

x y
0 -1.0 -10.715459
1 -1.0 -9.972410
2 -1.0 -30.740532
3 -1.0 -31.368963
4 -1.0 -29.058633

fcp.plot(df_interval, x='x', y='y', lines=False, conf_int=0.95)

Control limits


fcp.plot(df_interval, x='x', y='y', lines=False, ucl=50, lcl=-50, ucl_fill_color='#FF0000', legend=True)

Reference line


fcp.plot(df_xy, x='Voltage', y='I [A]', title='IV Data', legend='Die',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25',
         ref_line=df_xy['Voltage'], ref_line_legend_text='y=x', xmin=0, ymin=0, xmax=1.6, ymax=1.6)

bar

Simple


fcp.bar(df_bar, x='Liquid', y='pH', filter='Measurement=="A" & T [C]==25', horizontal=True)

Legend


fcp.bar(df_bar, x='Liquid', y='pH', tick_labels_major_x_rotation=90, legend='Measurement')

Stacked


fcp.bar(df_bar, x='Liquid', y='pH', tick_labels_major_x_rotation=90, stacked=True, legend='Measurement')

Grouping


fcp.bar(df_bar, x='Liquid', y='pH', tick_labels_major_x_rotation=90, col='Measurement', row='T [C]', ax_hlines=0, ax_size=[300, 300])

boxplot

Basic


fcp.boxplot(df_box, y='Value', groups=['Batch', 'Sample'], group_means=True)

Legend


df_box['Row'] = [int(f) for f in df_box.index / 4]
fcp.boxplot(df_box, y='Value', groups=['Batch', 'Sample'], mean_diamonds=True, conf_coeff=0.95, legend='Row')

Violins


fcp.boxplot(df_box, y='Value', groups=['Batch', 'Sample'], violin=True)

Grouping


fcp.boxplot(df_box, y='Value', groups=['Batch', 'Sample'], col='Region', ax_size=[300, 300])

Note

auto-sizing for boxplot is not yet available with plotly

contour

No fill


fcp.contour(df_contour, x='X', y='Y', z='Value', filled=False, cbar=False)

Points


fcp.contour(df_contour, x='X', y='Y', z='Value', filled=False, levels=40, contour_width=2,
            xmin=-4, xmax=5, ymin=-4, ymax=6, cbar=True,
            show_points=True, marker_size=26, marker_fill_color='#00FF00')

Grid with fill


fcp.contour(df_contour, x='X', y='Y', z='Value', row='Batch', col='Experiment', filled=True,
            cbar=False, xmin=-3, xmax=3, ymin=-3, ymax=3, ax_size=[250,250],
            label_rc_font_size=12, levels=40)

gantt

Better luck next time…

heatmap


fcp.heatmap(df_heatmap, x='Category', y='Player', z='Average')

hist

Basic


fcp.hist(df_hist, x='Value', horizontal=True, bins=20)

kde


fcp.hist(df_hist, x='Value', legend='Region', kde=True, kde_width=2)

Image


fcp.hist(img_rgb, legend='Channel', markers=False, ax_size=[600, 400], line_width=2, colors=fcp.RGB)

imshow

RGB


fcp.imshow(img_rgb, ax_size=[600, 300])

Raw / Grayscale


img_raw = fcp.utilities.img_grayscale(img_rgb)
fcp.imshow(img_raw, ax_size=[600, 600], title='Fake RAW, Fake Pirate', cbar=True, title_edge_width=1, title_edge_color='#ff0000')

Grid


url = 'https://upload.wikimedia.org/wikipedia/commons/2/28/RGB_illumination.jpg'
img_rgb_sp = imageio.imread(url)
img_raw_sp = fcp.utilities.rgb2bayer(img_rgb_sp)
fcp.imshow(img_raw_sp, cmap='inferno', ax_size=[300, 300], cfa='rggb', wrap='Plane', ax_edge_width=1, ax_edge_color='#555555')

nq

Basic


fcp.nq(df_box, x='Value', marker_size=4, line_width=2)

Image


img_rgb = cv2.imread(str(Path(fcp.__file__).parent / 'test_data/imshow_cat_pirate.png'))
img_cat = fcp.utl.img_grayscale(img_rgb, bit_depth=12)
fcp.nq(img_cat, marker_size=4, line_width=2)

pie

Basic


df_pie = df_bar.copy()
df_pie.loc[df_pie.pH < 0, 'pH'] = -df_pie.pH
fcp.pie(df_pie, x='Liquid', y='pH', filter='Measurement=="A" & T [C]==25')

Legend


fcp.pie(df_pie, x='Liquid', y='pH', filter='Measurement=="A" & T [C]==25', explode=[0.1], legend=True)